#ifndef __PCI_H
#define __PCI_H

#include <common/types.h>
#include <hardwarecommunication/port.h>
#include <driver/driver.h>
#include <common/common.h>
#include <hardwarecommunication/interrupts.h>

#include <memory/memorymanagement.h>


enum BaseAddressRegisterType{
    MemoryMapping = 0,
    InputOutput = 1
};

class BaseAddressRegister{
    public:
        bool prefetchable;
        uint8_t* address;
        uint32_t size;
        BaseAddressRegisterType type;
};


class PciDeviceDescriptor{

    private:

    public:
        uint32_t portBase;
        uint32_t interrupt;

        uint16_t bus;
        uint16_t device;
        uint16_t function;

        uint16_t vendor_id;
        uint16_t device_id;
        uint16_t class_id;
        uint16_t subClass_id;
        uint16_t interface_id;
        uint16_t revision;
        PciDeviceDescriptor();
        ~PciDeviceDescriptor();


};


class Pci
{
private:
    
    Port32Bit dataPort;
    Port32Bit commandPort;
    /* data */
public:
    Pci(/* args */);
    ~Pci();
    uint32_t Read(uint16_t bus,uint16_t device,uint16_t function,uint32_t registerOffset);
    void Write(uint16_t bus,uint16_t device,uint16_t function,uint32_t registerOffset,uint32_t value);
    bool DeviceHasFunctions(uint16_t bus,uint16_t device);
    void SelectDriver(DriverManager* driverManager,InterruptManager* interruptManager);
    PciDeviceDescriptor GetDeviceDescriptor(uint16_t bus,uint16_t device,uint16_t function);
    BaseAddressRegister GetBaseAddressRegister(uint16_t bus,uint16_t device,uint16_t function, uint16_t bar);
    Driver* GetDriver(PciDeviceDescriptor, InterruptManager*);
};





#endif